package services

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"simple-crm/models"
	"time"

	"gorm.io/gorm"
)

type PushService struct {
	DB *gorm.DB
}

type PushData struct {
	Customer models.Customer `json:"customer"`
	Source   string          `json:"source"`
	PushTime time.Time       `json:"push_time"`
}

type PartnerMatchResult struct {
	Partner    models.Partner     `json:"partner"`
	MatchScore int                `json:"match_score"`
	MatchType  string             `json:"match_type"`
	Reason     string             `json:"reason"`
	PushRecord *models.PushRecord `json:"push_record,omitempty"`
}

type PushStats struct {
	TotalPush   int64   `json:"total_push"`
	SuccessPush int64   `json:"success_push"`
	FailedPush  int64   `json:"failed_push"`
	PendingPush int64   `json:"pending_push"`
	ManualPush  int64   `json:"manual_push"`
	SuccessRate float64 `json:"success_rate"`
}

// NewPushService 创建推送服务
func NewPushService(db *gorm.DB) *PushService {
	return &PushService{DB: db}
}

// ManualPushCustomer 手动推送客户
func (ps *PushService) ManualPushCustomer(customerID, partnerID, pushedBy uint, notes string) (*models.PushRecord, error) {
	// 获取客户信息
	var customer models.Customer
	if err := ps.DB.First(&customer, customerID).Error; err != nil {
		return nil, err
	}

	// 获取合作机构信息
	var partner models.Partner
	if err := ps.DB.First(&partner, partnerID).Error; err != nil {
		return nil, err
	}

	// 执行推送
	return ps.pushToPartnerWithPriority(customer, partner, "manual", 0, "手动推送", pushedBy, notes)
}

// pushToPartnerWithPriority 按优先级推送到合作机构
func (ps *PushService) pushToPartnerWithPriority(customer models.Customer, partner models.Partner, pushType string, matchScore float64, matchType string, pushedBy uint, notes string) (*models.PushRecord, error) {
	// 创建推送记录
	pushRecord := models.PushRecord{
		CustomerID: customer.ID,
		PartnerID:  partner.ID,
		PushType:   pushType,
		Status:     "pending",
		MatchScore: matchScore,
		MatchType:  matchType,
		Notes:      notes,
		PushedBy:   pushedBy,
		PushedAt:   time.Now(),
	}

	if err := ps.DB.Create(&pushRecord).Error; err != nil {
		return nil, err
	}

	// // 发送推送请求
	// response, err := ps.sendPushRequest(customer, partner)
	// if err != nil {
	// 	// 更新推送记录为失败
	// 	pushRecord.MarkFailed(ps.DB, err.Error())
	// 	return &pushRecord, err
	// }

	response := "成功"
	// 更新推送记录为成功
	pushRecord.MarkSuccess(ps.DB, response)

	// 标记客户为已推送
	customer.MarkAsPushed(ps.DB)

	return &pushRecord, nil
}

// sendPushRequest 发送推送请求
func (ps *PushService) sendPushRequest(customer models.Customer, partner models.Partner) (string, error) {
	if partner.WebhookURL == "" {
		return "", errors.New("合作机构未配置Webhook URL")
	}

	// 构建推送数据
	pushData := PushData{
		Customer: customer,
		Source:   "simple-crm",
		PushTime: time.Now(),
	}

	// 序列化数据
	jsonData, err := json.Marshal(pushData)
	if err != nil {
		return "", err
	}

	// 创建HTTP请求
	req, err := http.NewRequest("POST", partner.WebhookURL, bytes.NewBuffer(jsonData))
	if err != nil {
		return "", err
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")
	if partner.APIKey != "" {
		req.Header.Set("Authorization", "Bearer "+partner.APIKey)
	}
	req.Header.Set("User-Agent", "Simple-CRM/1.0")

	// 发送请求
	client := &http.Client{
		Timeout: 30 * time.Second,
	}
	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	// 检查响应状态
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		return "", fmt.Errorf("推送失败，状态码: %d", resp.StatusCode)
	}

	// 读取响应内容
	buf := new(bytes.Buffer)
	buf.ReadFrom(resp.Body)
	responseBody := buf.String()

	return responseBody, nil
}

// RetryPush 重试推送
func (ps *PushService) RetryPush(pushRecordID, pushedBy uint) (*models.PushRecord, error) {
	// 获取推送记录
	var pushRecord models.PushRecord
	if err := ps.DB.Preload("Customer").Preload("Partner").First(&pushRecord, pushRecordID).Error; err != nil {
		return nil, err
	}

	// 检查是否可以重试
	if !pushRecord.CanRetry() {
		return nil, errors.New("推送记录不允许重试")
	}

	// 增加重试次数
	if err := pushRecord.IncrementRetry(ps.DB); err != nil {
		return nil, err
	}

	// 重新发送推送请求
	response, err := ps.sendPushRequest(pushRecord.Customer, pushRecord.Partner)
	if err != nil {
		// 更新推送记录为失败
		pushRecord.MarkFailed(ps.DB, err.Error())
		return &pushRecord, err
	}

	// 更新推送记录为成功
	pushRecord.MarkSuccess(ps.DB, response)

	// 标记客户为已推送
	pushRecord.Customer.MarkAsPushed(ps.DB)

	return &pushRecord, nil
}

// GetPushRecords 获取推送记录列表
func (ps *PushService) GetPushRecords(page, limit int, status, pushType string, customerID, partnerID uint) ([]models.PushRecord, int64, error) {
	offset := (page - 1) * limit

	query := ps.DB.Model(&models.PushRecord{}).Preload("Customer").Preload("Partner").Preload("PushedByUser")

	if status != "" {
		query = query.Where("status = ?", status)
	}

	if pushType != "" {
		query = query.Where("push_type = ?", pushType)
	}

	if customerID > 0 {
		query = query.Where("customer_id = ?", customerID)
	}

	if partnerID > 0 {
		query = query.Where("partner_id = ?", partnerID)
	}

	var total int64
	query.Count(&total)

	var records []models.PushRecord
	err := query.Order("created_at DESC").Offset(offset).Limit(limit).Find(&records).Error

	return records, total, err
}

// GetRecommendedPartners 获取推荐的合作机构
func (ps *PushService) GetRecommendedPartners(customerID uint) ([]PartnerMatchResult, error) {
	// 获取客户信息
	var customer models.Customer
	if err := ps.DB.First(&customer, customerID).Error; err != nil {
		return nil, err
	}

	// 获取所有活跃的合作机构
	var partners []models.Partner
	if err := ps.DB.Where("status = ?", "active").Find(&partners).Error; err != nil {
		return nil, err
	}

	// 构建推荐结果
	var results []PartnerMatchResult
	for _, partner := range partners {
		// 检查是否已经推送过
		var existingRecord models.PushRecord
		alreadyPushed := ps.DB.Where("customer_id = ? AND partner_id = ?", customerID, partner.ID).First(&existingRecord).Error == nil

		result := PartnerMatchResult{
			Partner:    partner,
			MatchScore: ps.calculateMatchScore(customer, partner),
			MatchType:  "manual",
			Reason:     ps.getMatchReason(customer, partner),
		}

		if alreadyPushed {
			result.PushRecord = &existingRecord
		}

		results = append(results, result)
	}

	return results, nil
}

// calculateMatchScore 计算匹配分数
func (ps *PushService) calculateMatchScore(customer models.Customer, partner models.Partner) int {
	score := 50 // 基础分数

	// 根据客户和合作机构的匹配度计算分数
	// 这里可以根据具体业务逻辑进行调整
	if customer.City == partner.City {
		score += 20
	}

	// 检查客户科目是否在合作机构的科目列表中
	if customer.Subject != "" && partner.Subjects != "" {
		// 简单的字符串包含检查，实际项目中可能需要更复杂的匹配逻辑
		if len(customer.Subject) > 0 && len(partner.Subjects) > 0 {
			score += 30
		}
	}

	return score
}

// getMatchReason 获取匹配原因
func (ps *PushService) getMatchReason(customer models.Customer, partner models.Partner) string {
	reasons := []string{}

	if customer.City == partner.City {
		reasons = append(reasons, "城市匹配")
	}

	if customer.Subject != "" && partner.Subjects != "" {
		if len(customer.Subject) > 0 && len(partner.Subjects) > 0 {
			reasons = append(reasons, "科目匹配")
		}
	}

	if len(reasons) == 0 {
		return "基础匹配"
	}

	return fmt.Sprintf("%v", reasons)
}

// GetPushStats 获取推送统计
func (ps *PushService) GetPushStats() (*PushStats, error) {
	stats := &PushStats{}

	// 总推送数
	ps.DB.Model(&models.PushRecord{}).Count(&stats.TotalPush)

	// 成功推送数
	ps.DB.Model(&models.PushRecord{}).Where("status = ?", "success").Count(&stats.SuccessPush)

	// 失败推送数
	ps.DB.Model(&models.PushRecord{}).Where("status = ?", "failed").Count(&stats.FailedPush)

	// 待推送数
	ps.DB.Model(&models.PushRecord{}).Where("status = ?", "pending").Count(&stats.PendingPush)

	// 手动推送数
	ps.DB.Model(&models.PushRecord{}).Where("push_type = ?", "manual").Count(&stats.ManualPush)

	// 计算成功率
	if stats.TotalPush > 0 {
		stats.SuccessRate = float64(stats.SuccessPush) / float64(stats.TotalPush) * 100
	}

	return stats, nil
}
